﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using YArchitech.Revit;

namespace YArchitech.Temp
{
	public class HYDuctSystem : HYSystem
	{
		public bool IsConfluence { get; set; }

		public Document RevitDoc { get; set; }

		public HYDuctSystem()
		{
			base.Name = "盈建科风系统";
			this.IsConfluence = false;
		}

		public override void WriteXml(XElement xe)
		{
			base.WriteXml(xe);
			xe.SetAttributeValue("IsConfluence", this.IsConfluence);
		}

		public override void ReadXml(XElement xe)
		{
			base.ReadXml(xe);
			this.IsConfluence = xe.GetBoolAttribute("IsConfluence", false);
		}

		private double GetDesignVelocity(HYDuctStraight straight, HYDuctSystemOption option)
		{
			switch (straight.Place)
			{
			case HYMEPObject.BranchPlace.Main:
				return option.DesignVelocity_Main;
			case HYMEPObject.BranchPlace.Side:
				return option.DesignVelocity_Side;
			case HYMEPObject.BranchPlace.SideSide:
				return option.DesignVelocity_SideSdie;
			default:
				return option.DesignVelocity_Main;
			}
		}

		public void ResietPlace()
		{
			List<HYMEPObject> list = null;
			if (base.GetAllTerminals(out list) <= 0)
			{
				return;
			}
			foreach (HYMEPObject hymepobject in list)
			{
				HYMEPObject.BranchPlace place = HYMEPObject.BranchPlace.Side;
				for (HYMEPObject previous = hymepobject.Previous; previous != null; previous = previous.Previous)
				{
					if (previous is HYDuctStraight)
					{
						if ((previous as HYDuctStraight).HasTaper)
						{
							place = HYMEPObject.BranchPlace.Main;
						}
						previous.Place = place;
					}
					if (previous is HYDuctTee || previous is HYDuctCross)
					{
						place = HYMEPObject.BranchPlace.Main;
					}
				}
			}
		}

		private void CheckRiserDir()
		{
			List<HYMEPObject> list = null;
			if (base.GetAllTerminals(out list) <= 0)
			{
				return;
			}
			using (Transaction transaction = new Transaction(this.RevitDoc, "CheckRiserDir"))
			{
				try
				{
					transaction.Start();
					foreach (HYMEPObject hymepobject in list)
					{
						while (!(hymepobject is HYDuctStraight))
						{
                            HYMEPObject hymepobject2 = hymepobject.Previous;
						}
						if (hymepobject is HYDuctStraight && (hymepobject as HYDuctStraight).IsRiserDuct && (hymepobject as HYDuctStraight).Shape != HYShapeProfile.Round)
						{
							HYMEPObject previous = hymepobject.Previous;
							while (!(previous is HYDuctStraight))
							{
								previous = previous.Previous;
							}
							if (previous is HYDuctStraight)
							{
								this.ModifyDuctDir(this.GetRevitDuct(hymepobject as HYDuctStraight), this.GetRevitDuct(previous as HYDuctStraight));
							}
						}
					}
					transaction.Commit();
				}
				catch (Exception)
				{
					if (transaction != null && (int)transaction.GetStatus() != 3)
					{
						transaction.RollBack();
					}
				}
			}
		}

		private Duct GetRevitDuct(HYDuctStraight hyStraight)
		{
			ElementId elementId = new ElementId(hyStraight.Id);
			Element elementById = this.RevitDoc.GetElementById(elementId);
			if (elementById == null)
			{
				return null;
			}
			Duct duct = elementById as Duct;
			if (duct == null)
			{
				return null;
			}
			return duct;
		}

		private void ModifyDuctDir(Duct ductFrom, Duct ductTo)
		{
			if (ductFrom == null || ductTo == null)
			{
				return;
			}
			XYZ xyz = null;
			foreach (object obj in ductTo.ConnectorManager.Connectors)
			{
				xyz = ((Connector)obj).CoordinateSystem.BasisX;
				if (xyz != null)
				{
					break;
				}
			}
			XYZ xyz2 = null;
			foreach (object obj2 in ductFrom.ConnectorManager.Connectors)
			{
				xyz2 = ((Connector)obj2).CoordinateSystem.BasisX;
				if (xyz2 != null)
				{
					break;
				}
			}
			if (xyz2 == null || xyz == null)
			{
				return;
			}
			if (xyz2.IsAlmostEqualTo(xyz, 0.001) || xyz2.IsAlmostEqualTo(-1.0 * xyz, 0.001))
			{
				return;
			}
			LocationCurve locationCurve = ductFrom.Location as LocationCurve;
			if (locationCurve != null)
			{
				Line line = Line.CreateBound(locationCurve.Curve.GetEndPoint(0), locationCurve.Curve.GetEndPoint(1));
				locationCurve.Rotate(line, Math.PI*.5);
			}
		}

		public bool Design(HYDuctSystemOption option, HYDuctSpecifications mainSpecs, HYDuctSpecifications sideSpecs, HYDuctSpecifications roundSpecs, HYDuctSpecifications rectSpecs)
		{
			this.m_RootObject.ReAllocateFlow();
			this.ResietPlace();
			this.CheckRiserDir();
			FlowToSpecifications flowToSpecifications = new FlowToSpecifications();
			FlowToSpecifications flowToSpecifications2 = new FlowToSpecifications();
			IEnumerable<HYMEPObject> enumerable = from pl in this.m_Objects
			where pl is HYDuctStraight
			orderby pl.Flow
			select pl;
			base.ErrorString = "";
			foreach (HYMEPObject hymepobject in enumerable)
			{
				HYDuctStraight hyductStraight = (HYDuctStraight)hymepobject;
				double designVelocity = this.GetDesignVelocity(hyductStraight, option);
				HYDuctSpecification hyductSpecification = new HYDuctSpecification(HYShapeProfile.Rectangular, 800, 320);
				if (HYShapeProfile.Rectangular == hyductStraight.Shape)
				{
					HYMEPObject.BranchPlace place = hyductStraight.Place;
					HYDuctSpecifications sections;
					FlowToSpecifications flowToSpecs;
					if (place != HYMEPObject.BranchPlace.Side)
					{
						if (place != HYMEPObject.BranchPlace.SideSide)
						{
							sections = mainSpecs;
							flowToSpecs = flowToSpecifications;
						}
						else
						{
							sections = sideSpecs;
							flowToSpecs = flowToSpecifications2;
						}
					}
					else
					{
						sections = sideSpecs;
						flowToSpecs = flowToSpecifications2;
					}
					hyductSpecification = this.CalSection(hyductStraight.Flow, designVelocity, sections, flowToSpecs);
					bool isRiserDuct = hyductStraight.IsRiserDuct;
					if (hyductSpecification == null)
					{
						base.ErrorString = "计算过程中没有可用风管规格，请检查:\n设置->参数设置->计算参数\n关于风管规格选取的设定！";
						return false;
					}
				}
				else if (hyductStraight.Shape == HYShapeProfile.Round)
				{
					hyductSpecification = roundSpecs.SelectSectionByVelocity(hyductStraight.Flow, designVelocity);
					if (hyductSpecification == null)
					{
						base.ErrorString = "计算过程中没有可用风管规格，请检查:\n设置->参数设置->计算参数\n关于风管规格选取的设定！";
						return false;
					}
				}
				hyductStraight.Width = hyductSpecification.Width;
				hyductStraight.Diameter = hyductSpecification.Diameter;
				hyductStraight.Height = hyductSpecification.Height;
			}
			return this.Check(option);
		}

		public void CalAttachedObjects(HYDuctSystemOption option)
		{
			foreach (HYMEPObject hymepobject in from att in this.m_Objects
			where !(att is HYPipeline)
			select att)
			{
				hymepobject.Cal(option);
			}
		}

		public bool Check(HYDuctSystemOption option)
		{
			List<HYPipeline> list;
			base.GetAllPipelines(out list);
			foreach (HYPipeline hypipeline in list)
			{
				(hypipeline as HYDuctStraight).CalVelocity();
			}
			this.CalAttachedObjects(option);
			foreach (HYPipeline hypipeline2 in list)
			{
				(hypipeline2 as HYDuctStraight).Cal(option);
			}
			foreach (HYBranch hybranch in this.m_Branches)
			{
				hybranch.Cal();
			}
			HYBranch maxResistanceBranch = base.GetMaxResistanceBranch();
			foreach (HYBranch hybranch2 in this.m_Branches)
			{
				hybranch2.CalUnbalanceRate(maxResistanceBranch.Resistance);
			}
			return true;
		}

		private HYDuctSpecification CalSection(double flow, double designVelocity, HYDuctSpecifications sections, FlowToSpecifications flowToSpecs)
		{
			HYDuctSpecification hyductSpecification = flowToSpecs.GetSpecification(flow);
			if (hyductSpecification != null)
			{
				return hyductSpecification;
			}
			HYDuctSpecifications hyductSpecifications = new HYDuctSpecifications();
			if (flowToSpecs.Count > 0)
			{
				HYDuctSpecification dsMax = flowToSpecs.Max.Specification;
				hyductSpecifications.UnionWith(from section in sections
				where section > dsMax
				select section);
			}
			else
			{
				hyductSpecifications.UnionWith(sections);
			}
			hyductSpecification = hyductSpecifications.SelectSectionByVelocity(flow, designVelocity);
			flowToSpecs.Add(new FlowToSpecification
			{
				Flow = flow,
				Specification = hyductSpecification
			});
			return hyductSpecification;
		}

		private HYDuctSpecification GetRiserSection(double area, HYDuctSpecifications sections)
		{
			IList<HYDuctSpecification> list = new List<HYDuctSpecification>();
			foreach (HYDuctSpecification hyductSpecification in sections)
			{
				if (hyductSpecification.Width == hyductSpecification.Height)
				{
					list.Add(hyductSpecification);
				}
			}
			list = (from section in list
			orderby section.D
			select section).ToList<HYDuctSpecification>();
			int num = 0;
			foreach (HYDuctSpecification hyductSpecification2 in list)
			{
				if ((double)(hyductSpecification2.Height * hyductSpecification2.Width) > area)
				{
					break;
				}
				num++;
			}
			HYDuctSpecification result;
			if (num > 0)
			{
				double value = (double)(list[num].Width * list[num].Height) - area;
				double value2 = (double)(list[num - 1].Width * list[num - 1].Height) - area;
				result = ((Math.Abs(value) > Math.Abs(value2)) ? list[num - 1] : list[num]);
			}
			else
			{
				result = list[num];
			}
			return result;
		}

		public void Update()
		{
		}
	}
}
